package Project2.junitframe.framework;

import Project2.junitframe.annotation.*;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

public class RunMyTest2 {
	public static void Run(Class Clazz){
		Class<Object> a = Clazz;
		
		Method[] methods = a.getDeclaredMethods();
		
		List<Method> tests = new ArrayList<>();
		List<Method> before = new ArrayList<>();
		List<Method> afters = new ArrayList<>();
		List<Method> beforeClass = new ArrayList<>();
		List<Method> afterClass = new ArrayList<>();
		
//		Class<?>[] classes = null;
//		if (a.isAnnotationPresent(MyJUnitConfig.class)){
//			MyJUnitConfig myJUnitConfig = a.getAnnotation(MyJUnitConfig.class);
//			classes = myJUnitConfig.classes();
//		}
		
		Enhancer enhancer = new Enhancer(); // 创建增强器
		enhancer.setSuperclass(a); // 设置父类
		enhancer.setCallback(new MethodInterceptor() {
			/*
			*  o: 被代理的对象
			*  method: 被代理的方法
			*  objects: 方法的参数
			*  methodProxy: 方法的代理对象
			* */
			@Override
			public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
				System.out.println("proxy");
				return null;
			}
		});
		Object o = enhancer.create(); // 创建代理对象
		
		// 处理 注解类型 与 方法
		for (Method method : methods){
			Annotation[] annotations = method.getAnnotations();
			for (Annotation annotation : annotations){
				if (annotation instanceof MyTest){
					tests.add(method);
				} else if (annotation instanceof MyBefore){
					before.add(method);
				} else if (annotation instanceof MyAfter){
					afters.add(method);
				}else if (annotation instanceof MyBeforeClass){
					beforeClass.add(method);
				} else if (annotation instanceof MyAfterClass){
					afterClass.add(method);
				}
			}
		}
		for (Method bf : beforeClass) { // 执行beforeClass方法
			try {
//				if (bf.getName().equals("func") && classes != null && classes.length > 0){
//					bf.invoke(null, (Object) classes);
//				}else {
					bf.invoke(null);
//				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		for (Method method : tests) {
			try {
				Object oa = a.newInstance();
				for (Method bf : before) {  // 执行before方法
					bf.invoke(o);
				}
				method.invoke(oa); // 执行test方法
				for (Method af : afters) { // 执行after方法
					af.invoke(oa);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		for (Method af : afterClass) { // 执行afterClass方法
			try {
				af.invoke(null);
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}
}
